/*
 * fEventDelegate.h
 *
 *  Created on: 2011-3-30
 *      Author: wangchao
 */

#ifndef FEVENTDELEGATE_H_
#define FEVENTDELEGATE_H_

struct EmptyArg
{

};

template< typename ValueType, typename ValueType1 = EmptyArg >
class EventHandlerTemplate
{
public:
    //typedef void(Observer::*MPTR_EventHandle)( ValueType );
    typedef void (*EventHandle)( void* object_ptr, ValueType );
public:
    void HandleEvent( ValueType value )
    {
        if( _observer && _handle )
        {
            ( *_handle )( _observer, value );
        }
    }
protected:
    EventHandle _handle;
    void* _observer;
public:
    template< class Observer, void(Observer::*EventHandle)( ValueType ) >
    void AttachEventHandler( Observer* observer )
    {
        _observer = observer;
        _handle = &method_stub< Observer, EventHandle > ;
    }
private:
    template< class Observer, void(Observer::*EventHandle)( ValueType ) >
    static void method_stub( void* object_ptr, ValueType v )
    {
        Observer* p = static_cast< Observer* > ( object_ptr );
        return ( p->*EventHandle )( v ); // #2
    }
};

class fButton;
class ButtonClickedEventHandler : public EventHandlerTemplate< const fButton& >
{

};

/*
 class Button
 {
 public:
 void DoClicked( )
 {

 Clicked.ClickedEventHandler( *this );

 }
 public:
 ButtonClickedEventHandler Clicked;

 };
 */

#endif /* FEVENTDELEGATE_H_ */
